package net.chasing.androidbaseconfig.util;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;

/**
 * 避免内存泄露：在onDestroy时取消动画
 */
public class AnimatorUtil {
    public static void alphaHide(View view, int duration, final OnAnimation animation) {
        alpha(view, duration, animation, 1f, 0f);
    }

    public static void alphaShow(View view, int duration, final OnAnimation animation) {
        alpha(view, duration, animation, 0f, 1f);
    }

    public static void alpha(View view, int duration, final OnAnimation animationListener, float... alphaNum) {
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "alpha", alphaNum);
        anim1.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(anim1);
        animSet.setDuration(duration);
        animSet.start();
    }

    public static void alpha(View view, int duration, final OnAnimation animationListener, boolean isRepeat, float... alphaNum) {
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "alpha", alphaNum);
        anim1.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        if (isRepeat) {
            anim1.setRepeatCount(ValueAnimator.INFINITE);
            anim1.setRepeatMode(ValueAnimator.REVERSE);
        }
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(anim1);
        animSet.setDuration(duration);
        animSet.start();
    }

    public static AnimatorSet alphaWithTransitionY(View view, Animator.AnimatorListener listener, int duration, float alphaStart, float alphaEnd, float... position) {
        ObjectAnimator animAlpha = ObjectAnimator.ofFloat(view, "alpha", alphaStart, alphaEnd);
        ObjectAnimator animScale = ObjectAnimator.ofFloat(view, "translationY", position);
        AnimatorSet animSet = new AnimatorSet();
        if (listener != null)
            animSet.addListener(listener);
        animSet.play(animAlpha).with(animScale);
        animSet.setDuration(duration);
        animSet.start();
        return animSet;
    }

    public static ObjectAnimator scaleYFromTop(View view, int duration, float... scale) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "scaleY", scale);
        view.setPivotX(view.getWidth() / 2f);
        view.setPivotY(0);
        anim.setDuration(duration);
        anim.start();
        return anim;
    }

    public static AnimatorSet scaleFromCenter(View view, Animator.AnimatorListener listener, int duration, float... scale) {
        view.setPivotX(view.getWidth() / 2f);
        view.setPivotY(view.getHeight() / 2f);
        ObjectAnimator animScaleX = ObjectAnimator.ofFloat(view, "scaleX", scale);
        ObjectAnimator animScaleY = ObjectAnimator.ofFloat(view, "scaleY", scale);
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(animScaleX).with(animScaleY);
        if (listener != null)
            animSet.addListener(listener);
        animSet.setDuration(duration);
        animSet.start();
        return animSet;
    }

    public static void translationX(View view, int duration, float... position) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", position);
        anim.setDuration(duration);
        anim.start();
    }

    public static void translationX(View view, int duration, final OnAnimation animationListener, float... position) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", position);
        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        anim.setDuration(duration);
        anim.start();
    }

    public static void translationY(View view, int duration, float... position) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationY", position);
        anim.setDuration(duration);
        anim.start();
    }

    public static void translationY(View view, int duration, final OnAnimation animationListener, float... position) {
        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationY", position);
        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        anim.setDuration(duration);
        anim.start();
    }

    public static ObjectAnimator translationY(View view, int duration, boolean repeat, final OnAnimation animationListener, float... position) {
        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationY", position);
        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (animationListener != null)
                    animationListener.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        anim.setDuration(duration);
        if (repeat) {
            anim.setRepeatCount(ValueAnimator.INFINITE);
            anim.setRepeatMode(ValueAnimator.REVERSE);
        }
        anim.start();
        return anim;
    }

    /**
     * 通过改变高度达到移动效果
     * 注意：start不要从0开始，用1替代0，设置了0布局还是会完整显示
     */
    public static ValueAnimator translationYByHeight(final View v, int duration, final OnAnimation animationListener, int start, final int end) {
        if (start == 0)
            start = 1;
        ValueAnimator animator = ValueAnimator.ofInt(start, end);
        int finalStart = start;
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            private boolean hadStart = false;

            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator arg0) {
                int value = (int) arg0.getAnimatedValue();

                ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
                if (layoutParams.height != value) {
                    layoutParams.height = value;
                    v.setLayoutParams(layoutParams);
                }

                if (value == finalStart && animationListener != null && !hadStart) {
                    hadStart = true;
                    animationListener.onAnimationStart(arg0);
                } else if (value == end && animationListener != null)
                    animationListener.onAnimationEnd(arg0);
            }
        });
        animator.setDuration(duration);
        animator.start();
        return animator;
    }

    //通过改变marginTop达到移动效果
    public static ValueAnimator translationYByMargin(final View v, int duration, final OnAnimation animationListener, final int start, final int end) {
        ValueAnimator animator = ValueAnimator.ofInt(start, end);
        animator.addUpdateListener(arg0 -> {
            int value = (int) arg0.getAnimatedValue();
            if (value == start && animationListener != null)
                animationListener.onAnimationStart(arg0);

            ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
            if (layoutParams instanceof ViewGroup.MarginLayoutParams)
                ((ViewGroup.MarginLayoutParams) layoutParams).topMargin = value;
            v.setLayoutParams(layoutParams);
            if (value == end && animationListener != null)
                animationListener.onAnimationEnd(arg0);
        });
        animator.setDuration(duration);
        animator.start();
        return animator;
    }

    //旋转
    public static ObjectAnimator rotate(View view, int duration, float... degree) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "rotation", degree);
        anim.setDuration(duration);
        anim.start();
        return anim;
    }

    public static ObjectAnimator rotateRepeat(View view, int duration, int repeat, float... degree) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "rotation", degree);
        anim.setDuration(duration);
        anim.setRepeatCount(repeat);
        anim.setInterpolator(new LinearInterpolator());
        anim.start();
        return anim;
    }

    public interface OnAnimation {
        void onAnimationStart(Animator animation);

        void onAnimationEnd(Animator animation);
    }
}
